using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Admin.Controls;
using PHSRAG.Insight21.Policy;
using PHSRAG.Security.Enumerations;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.Admin
{
    /// <summary>
    /// Wizard page for editing labs. The page hosts three web custom controls each of which
    /// appears as distinct page by clicking the next or back button.
    /// Custom placeholder control is used to load user controls. 
    /// </summary>
    public partial class Migrated_EditAdminLabAccessWizard : EditAdminLabAccessWizard
    {
        #region Constants

        private const string AccessWizardControlKey = "AccessWizardControlKey_FE9C703E-BC6E-4968-812B-E9898116AB52";
        private const string AccessWizardControlPath = "AdminControls/EditAdminLabAccess.ascx";
        private const string CloseAndRefreshPopupClientScriptKey = "ScriptKey_HR9C703E-BC6E-4968-812B-E9898116AB99";
        private const string ClosePopupClientScriptKey = "ScriptKey_FE9C703E-BC6E-4968-812B-E9898116AB52";
        private const string ModulesWizardControlKey = "ModulesWizardControlKey_FE9C703E-BC6E-4968-812B-E9898116AB52";
        private const string ModulesWizardControlPath = "AdminControls/EditAdminLabAccessModules.ascx";
        private const string RightsWizardControlKey = "RightsWizardControlKey_FE9C703E-BC6E-4968-812B-E9898116AB52";
        private const string RightsWizardControlPath = "AdminControls/EditAdminLabAccessRights.ascx";

        #endregion

        #region Private Variables

        /// <summary>Contains key/value pairs of wizard user controls </summary>
        private Hashtable editLabWizardPageInfo;

        /// <summary>Policy used for caching business objects.</summary>
        private ICachePolicy objectCachePolicy;

        /// <summary>Policy used for caching objects to be used across pages. </summary>
        private ICachePolicy pageCachePolicy;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the current page number.
        /// </summary>
        public override int CurrentPageNumber
        {
            get { return Convert.ToInt32(pageNumber.Text); }
        }

        /// <summary>
        /// Gets the hashtable of wizard pages information from session. If not in session,
        /// returns a new instance of the hashtable.
        /// Also places the modified page hashtable to session.
        /// </summary>
        public override Hashtable EditLabWizardPageInfo
        {
            get
            {
                if (editLabWizardPageInfo == null)
                {
                    editLabWizardPageInfo = (Hashtable) pageCachePolicy.GetCachedObject(Keys.EditLabAccessWizardPageKey);
                }
                return editLabWizardPageInfo ?? (editLabWizardPageInfo = new Hashtable());
            }
            set { pageCachePolicy.Cache(Keys.EditLabAccessWizardPageKey, value); }
        }

        /// <summary>
        /// Gets the Lab being updated. Checks the cache first, if empty
        /// retrieves it from the database.
        /// </summary>
        public override Lab CurrentLab
        {
            get
            {
                Lab lab = objectCachePolicy.GetCachedObject(Lab.CacheKey) as Lab;

                if (lab == null)
                {
                    lab = new Lab(objectCachePolicy);
                    Hashtable incomingData = (Hashtable) pageCachePolicy.GetCachedObject(Keys.IncomingDataKey);
                    lab.Load(DataAccess.GetConnectionString(), Convert.ToInt32(incomingData[Keys.LabIdKey]));
                    lab.Cache();
                }

                return lab;
            }
        }

        /// <summary>
        /// Checks if the agreement module was selected in the module page of the wizard.
        /// </summary>
        public override bool IsAgreementsModuleSelected
        {
            get
            {
                DataGrid dataGrid = (DataGrid) ((EditAdminLabAccessModules) EditLabWizardPageInfo[ModulesWizardControlKey]).FindControl("dataGrid");

                foreach (DataGridItem item in dataGrid.Items)
                {
                    if (Convert.ToInt32(item.Cells[0].Text) == (int) ModuleBit.Agreements)
                    {
                        return ((CheckBox) item.FindControl("isSelected")).Checked;
                    }
                }

                return false;
            }
        }

        /// <summary>
        /// Checks if the humans module was selected in the module page of the wizard.
        /// </summary>
        public override bool IsHumansModuleSelected
        {
            get
            {
                DataGrid dataGrid = (DataGrid) ((EditAdminLabAccessModules) EditLabWizardPageInfo[ModulesWizardControlKey]).FindControl("dataGrid");

                foreach (DataGridItem item in dataGrid.Items)
                {
                    if (Convert.ToInt32(item.Cells[0].Text) == (int) ModuleBit.Humans)
                    {
                        return ((CheckBox) item.FindControl("isSelected")).Checked;
                    }
                }

                return false;
            }
        }

        /// <summary>
        /// Checks if the purchasing module was selected in the module page of the wizard.
        /// </summary>
        public override bool IsPurchasingModuleSelected
        {
            get
            {
                DataGrid dataGrid = (DataGrid) ((EditAdminLabAccessModules) EditLabWizardPageInfo[ModulesWizardControlKey]).FindControl("dataGrid");

                foreach (DataGridItem item in dataGrid.Items)
                {
                    if (Convert.ToInt32(item.Cells[0].Text) == (int) ModuleBit.Purchasing)
                    {
                        return ((CheckBox) item.FindControl("isSelected")).Checked;
                    }
                }

                return false;
            }
        }

        #endregion

        #region Private Properties

        /// <summary>
        /// Gets the Rights bitmask to be assigned to all users being given access to a lab.
        /// </summary>
        private int LabRightsBitMask
        {
            get
            {
                int labRightsBitMask = 0;
                EditAdminLabAccessRights control = (EditAdminLabAccessRights) EditLabWizardPageInfo[RightsWizardControlKey];

                if (IsAgreementsModuleSelected)
                {
                    if (((CheckBox) control.FindControl("viewFinInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewFinancialInformation;
                    }
                    if (((CheckBox) control.FindControl("viewSalInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewSalaryInformation;
                    }
                    if (((CheckBox) control.FindControl("viewAccess")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewAccess;
                    }
                    if (((CheckBox) control.FindControl("viewPendingAgr")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewPendingAgreements;
                    }
                }

                if (IsHumansModuleSelected)
                {
                    if (((CheckBox) control.FindControl("viewProtInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewProtocolInformation;
                    }
                    if (((CheckBox) control.FindControl("editProtInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.EditProtocolInformation;
                    }
                    if (((CheckBox) control.FindControl("manageProtInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ManageProtocolInformation;
                    }
                }

                if (IsPurchasingModuleSelected)
                {
                    if (((CheckBox) control.FindControl("viewPeoplesoftInfo")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewPeoplesoftInformation;
                    }
                    if (((CheckBox) control.FindControl("viewUserOrder")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ViewUserOrder;
                    }
                    if (((CheckBox) control.FindControl("manageUserOrder")).Checked)
                    {
                        labRightsBitMask |= (int) AccessRightBit.ManageUserOrder;
                    }
                }

                return labRightsBitMask;
            }
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Occurs when the page is loaded.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Argument associated with the event</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Lab lab = CurrentLab;
                labName.Text = lab.Name;
                labDescription.Text = lab.Description;
                labOrganization.Text = lab.Organization;

                pageNumber.Text = "1";
                ManageNavigationButtons();
                placeHolder.Controls.Clear();
                placeHolder.Controls.Add(LoadControl(AccessWizardControlPath));
            }
        }

        /// <summary>
        /// Caches the current user control in the placeholder before loading the "next" user control to be displayed.
        /// The sequence in which the user controls are loaded into the placeholder is predetermined, consequently
        /// they are loaded based on the current page number.
        /// Disables search criteria validation on the EditAdminLabAccess user control if there are already users 
        /// in the lab.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Argument associated with the event</param>
        protected void OnNext(object sender, EventArgs e)
        {
            int currentPageNumber = CurrentPageNumber;
            if (currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccess && CurrentLab.Access.Rows.Count != 0)
            {
                ((EditAdminLabAccess) placeHolder.Controls[0]).EnableSearchCriteriaValidation = false;
            }

            if (Page.IsValid)
            {
                Control control = null;

                if (currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccessModules)
                {
                    EditLabWizardPageInfo[ModulesWizardControlKey] = placeHolder.Controls[0];
                    placeHolder.Controls.Clear();
                    control = EditLabWizardPageInfo[RightsWizardControlKey] as Control;
                    if (control == null)
                    {
                        control = LoadControl(RightsWizardControlPath);
                    }
                    else
                    {
                        control.FindControl("agreementsRow").Visible = IsAgreementsModuleSelected;
                        control.FindControl("purchasingRow").Visible = IsPurchasingModuleSelected;
                        control.FindControl("humansRow").Visible = IsHumansModuleSelected;
                    }
                }
                else if (currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccess)
                {
                    ((EditAdminLabAccess) placeHolder.Controls[0]).EnableSearchCriteriaValidation = true;

                    EditLabWizardPageInfo[AccessWizardControlKey] = placeHolder.Controls[0];
                    placeHolder.Controls.Clear();
                    control = EditLabWizardPageInfo[ModulesWizardControlKey] as Control ?? LoadControl(ModulesWizardControlPath);
                }

                // put the modified hash back to cache
                EditLabWizardPageInfo = EditLabWizardPageInfo;

                ++currentPageNumber;
                pageNumber.Text = currentPageNumber.ToString();
                placeHolder.Controls.Add(control);

                ManageNavigationButtons();
            }
        }

        /// <summary>
        /// Caches the current user control in the placeholder before loading the "previous" user control to be displayed.
        /// The sequence in which the user controls are loaded into the placeholder is predetermined, consequently
        /// they are loaded based on the current page number.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Argument associated with the event</param>		
        protected void OnBack(object sender, EventArgs e)
        {
            int currentPageNumber = CurrentPageNumber;
            Control control = null;

            if (currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccessModules)
            {
                EditLabWizardPageInfo[ModulesWizardControlKey] = placeHolder.Controls[0];

                placeHolder.Controls.Clear();
                control = EditLabWizardPageInfo[AccessWizardControlKey] as Control ?? LoadControl(AccessWizardControlPath);
            }
            else if (currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccessRights)
            {
                EditLabWizardPageInfo[RightsWizardControlKey] = placeHolder.Controls[0];
                placeHolder.Controls.Clear();
                control = EditLabWizardPageInfo[ModulesWizardControlKey] as Control ?? LoadControl(ModulesWizardControlPath);
            }

            EditLabWizardPageInfo = EditLabWizardPageInfo;
            --currentPageNumber;
            pageNumber.Text = currentPageNumber.ToString();
            placeHolder.Controls.Add(control);

            ManageNavigationButtons();
        }

        /// <summary>
        /// Resets the lab dataset in memory, Clears page cache, and closes the wizard.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Argument associated with the event</param>	
        protected void OnCancel(object sender, EventArgs e)
        {
            CurrentLab.GetDataContainer().RejectChanges();

            pageCachePolicy.UnCache(Keys.EditLabAccessWizardPageKey);

            // close the popup 
            Page.ClientScript.RegisterClientScriptBlock(GetType(), ClosePopupClientScriptKey, "<script language='javascript'>window.close();</script>");
        }

        /// <summary>
        /// Persists all changes made to the lab to the database.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Argument associated with the event</param>
        protected void OnFinish(object sender, EventArgs e)
        {
            EditLabWizardPageInfo[RightsWizardControlKey] = placeHolder.Controls[0];
            EditLabWizardPageInfo = EditLabWizardPageInfo;

            int rightBitMask = LabRightsBitMask;
            Lab lab = CurrentLab;
            DataTable labAccessTable = lab.Access;

            foreach (DataRow dataRow in labAccessTable.Rows)
            {
                if (dataRow.RowState != DataRowState.Deleted)
                {
                    dataRow["RightBitMask"] = rightBitMask;
                }
            }

            lab.Cache();

            lab.Save(DataAccess.GetConnectionString(), LabCommandType.EditAccess);

            pageCachePolicy.UnCache(Keys.EditLabAccessWizardPageKey);

            // close the popup and refresh the opening page so that it displays the newly added lab
            Page.ClientScript.RegisterClientScriptBlock(GetType(), CloseAndRefreshPopupClientScriptKey, "<script language='javascript'>window.opener.location.reload();window.close();</script>");
        }

        #endregion

        #region Private Methods

        private void ManageNavigationButtons()
        {
            int currentPageNumber = CurrentPageNumber;
            next.Visible = currentPageNumber != (int) EditLabAccessWizardPage.EditAdminLabAccessRights;
            finish.Visible = currentPageNumber == (int) EditLabAccessWizardPage.EditAdminLabAccessRights;
            back.Visible = currentPageNumber != (int) EditLabAccessWizardPage.EditAdminLabAccess;
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Wires up page events.
        /// </summary>
        /// <param name="e">Information associated with the event.</param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);

            objectCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
        }

        #endregion
    }
}